package main

import (
	"errors"
	"fmt"
)

type Stack struct {
	Top *Block
}

func (s *Stack) Push(str string) {
	if s.Top == nil {
		s.Top = NewBlock(str)
	} else {
		s.Top = s.Top.Push(str)
	}
}
func (s *Stack) Pop() (string, error) {
	if s.Top == nil {
		return "", errors.New("no item found in the stack")
	} else {
		var str string
		s.Top, str = s.Top.Pop()
		return str, nil
	}
}
func (s *Stack) List() {
	now := s.Top
	if now == nil {
		return
	}
	for {
		fmt.Println(now.Data)
		if now == now.next {
			return
		} else {
			now = now.next
		}

	}
}

type Block struct {
	Data string
	pre  *Block
	next *Block
}

func NewBlock(s string) *Block {
	b := &Block{Data: s}
	b.pre = b
	b.next = b
	return b
}
func (b *Block) Push(s string) *Block {
	n := NewBlock(s)
	n.next = b
	b.pre = n
	return n
}
func (b *Block) Pop() (*Block, string) {
	if b.next == b {
		return nil, b.Data
	} else {
		return b.next, b.Data
	}
}
func main() {
	s := Stack{}
	for i := 0; i <= 10; i++ {
		s.Push(fmt.Sprintf("%d", i))
	}
	fmt.Println("-------")
	s.List()
	fmt.Println("-------")
	for {
		str, err := s.Pop()
		if err != nil {
			break
		}
		fmt.Println(str)
	}
	fmt.Println("---------------")
	s.List()
}
